package com.atguigu.srb.sms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.guigu.common.exception.BusinessException;
import com.atguigu.guigu.common.result.R;
import com.atguigu.guigu.common.result.ResultCodeEnum;
import com.atguigu.guigu.common.utils.HttpUtils;
import com.atguigu.guigu.common.utils.RandomUtils;
import com.atguigu.guigu.common.utils.RegexValidateUtils;
import com.atguigu.service.base.consts.SrbConsts;
import com.atguigu.srb.sms.config.SmsProperties;
import com.atguigu.srb.sms.feign.CoreClient;
import com.atguigu.srb.sms.service.SmsService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements SmsService {
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    CoreClient coreClient;
//    @Autowired
//    SmsProperties smsProperties;
    @Override
    public void sendMsg(String mobile, Integer type) {
        //1、验证手机号码格式：正则表达式
        boolean b = RegexValidateUtils.checkCellphone(mobile);
        if(!b){//手机号码验证失败 格式错误
            throw new BusinessException(ResultCodeEnum.MOBILE_ERROR);
        }
        //2分钟不能重复发送短信的key
        String  timesKey = SrbConsts.SMS_TIMES_PREFIX +mobile+":"+type;
        //1天获取次数不超过3次的key
        String countKey = SrbConsts.SMS_COUNT_PREFIX+mobile+":"+type;
        //验证码的key
        String  codeKey = SrbConsts.SMS_CODE_PREFIX+mobile+":"+type;
        //2、验证手机号码发送的频率
        //2.1 2分钟内不能重复获取
        if(stringRedisTemplate.hasKey(timesKey)){
            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
        }
        //2.2 一天内只能获取3条
        String countStr = stringRedisTemplate.opsForValue().get(countKey);
        if(StringUtils.isNotEmpty(countStr) && Integer.parseInt(countStr)>=3){
            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_COUNTS_CONTROL_ERROR);
        }
        //-- 验证手机号码是否已被占用
        // 操作会员表的服务是service-core，sms服务需要远程调用service-core才可以判断手机号码是否被占用
        R r = coreClient.isRegist(mobile);
        if(r.getCode()!=0 || !(boolean)(r.getData().get("flag"))){
            throw new BusinessException(ResultCodeEnum.MOBILE_EXIST_ERROR);
        }
        //3、调用第三方接口发送验证码
        try {
            String host = SmsProperties.HOST;
            String path = SmsProperties.PATH;
            String method = SmsProperties.METHOD;
            String appcode = SmsProperties.APPCODE;
            Map<String, String> headers = new HashMap<String, String>();
            //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
            headers.put("Authorization", "APPCODE " + appcode);
            Map<String, String> querys = new HashMap<String, String>();
            querys.put("mobile", mobile);
            String fourBitRandom = RandomUtils.getFourBitRandom();
            querys.put("param", "code:"+fourBitRandom);
            querys.put("tpl_id", SmsProperties.TPL_ID);
            Map<String, String> bodys = new HashMap<String, String>();
//            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            //解析响应内容
//            String result = EntityUtils.toString(response.getEntity(), "UTF-8");
//            Map map = JSON.parseObject(result, Map.class);
//            if("00000".equals(map.get("return_code"))){
                //短信发送成功
                //4、保存验证码到redis并设置过期时间 20分钟
                stringRedisTemplate.opsForValue().set(codeKey,fourBitRandom,20,
                        TimeUnit.MINUTES);
                //5、更新手机号码获取验证码的次数
                //2分钟内不能重复获取验证码
                stringRedisTemplate.opsForValue().set(timesKey,"1",2,
                        TimeUnit.MINUTES);

                //如果是第N次获取 在之前的次数上+1
                if(stringRedisTemplate.hasKey(countKey)){
                    //该手机号之前已经获取过验证码
                    stringRedisTemplate.opsForValue().increment(countKey);
                }else{
                    //如果第一次获取验证码  初始化获取验证码的次数为1 并设置过期时间24小时
                    stringRedisTemplate.opsForValue().set(countKey,"1",1,
                            TimeUnit.DAYS);
                }
//            }else{
//                throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_ERROR);
//            }
        } catch (Exception e) {
            throw new BusinessException(ResultCodeEnum.ALIYUN_SMS_ERROR,e);
        }


    }
}
